import logging

import oss2
import os
from dotenv import load_dotenv
from fastapi import  HTTPException


# 加载环境变量
load_dotenv()


class OSSClient:
        def __init__(self):
            self.allowed_mime_types = "application/msword,application/vnd.openxmlformats-officedocument.wordprocessingml.document"
            self.access_key_id ="LTAI5t7gXWXyKvbyAG6HgvZH"
            self.access_key_secret = "tQSyMIEU3vKpPkPzwfXAKJXmEAEvUx"
            self.endpoint = "https://oss-cn-hangzhou.aliyuncs.com"
            self.bucket_name = "hbut-testcase-requestfile"
            self.max_file_size = int(52428800)
            self.auth = oss2.Auth(self.access_key_id, self.access_key_secret)
            self.bucket = oss2.Bucket(self.auth, self.endpoint, self.bucket_name)

        # 添加公开的 upload_file 方法
        async def upload_file(self, file, file_id: str):
            """
            上传文件到OSS (公开接口)
            :param file: FastAPI UploadFile 对象
            :param file_id: 文件唯一ID
            :return: (oss_key, file_url, file_size)
            """
            return await self._upload_file(file, file_id)

        # 重命名私有方法为 _upload_file
        async def _upload_file(self, file, file_id: str):
            """
            内部实现：上传文件到OSS
            :param file: FastAPI UploadFile 对象
            :param file_id: 文件唯一ID
            :return: (oss_key, file_url, file_size)
            """
            try:
                # 读取文件内容
                file_content = await file.read()
                file_size = len(file_content)

                # 验证文件大小
                if file_size > self.max_file_size:
                    max_size_mb = self.max_file_size / (1024 * 1024)
                    raise HTTPException(
                        status_code=413,
                        detail=f"文件大小超过限制 ({max_size_mb}MB)"
                    )

                # 验证文件类型
                mime_type = self._detect_mime_type(file_content)
                if mime_type not in self.allowed_mime_types:
                    allowed_types = ", ".join(self.allowed_mime_types)
                    raise HTTPException(
                        status_code=415,
                        detail=f"不支持的文件类型. 只允许: {allowed_types}"
                    )

                # 获取文件扩展名
                _, ext = os.path.splitext(file.filename)
                ext = ext.lower()

                # 验证扩展名
                if mime_type == "application/msword" and ext != ".doc":
                    raise HTTPException(
                        status_code=415,
                        detail=".doc文件类型不匹配"
                    )
                if mime_type == "application/vnd.openxmlformats-officedocument.wordprocessingml.document" and ext != ".docx":
                    raise HTTPException(
                        status_code=415,
                        detail=".docx文件类型不匹配"
                    )

                # 生成OSS存储键
                oss_key = f"files/{file_id}{ext}"

                # 上传到OSS
                result = self.bucket.put_object(oss_key, file_content)
                if result.status != 200:
                    raise HTTPException(
                        status_code=500,
                        detail="OSS上传失败"
                    )

                # 生成文件URL (10年有效期)
                file_url = self.bucket.sign_url('GET', oss_key, 60 * 60 * 24 * 365 * 10)
                oss_bucket=self.bucket_name
                return oss_key, file_url, file_size,oss_bucket

            finally:
                # 重置文件指针
                await file.seek(0)

        def _detect_mime_type(self, file_content: bytes) -> str:
            """检测文件的MIME类型"""
            # 使用简单的文件头检测
            if len(file_content) > 8:
                # .docx 文件头 (PK\x03\x04)
                if file_content[0:4] == b'PK\x03\x04':
                    return "application/vnd.openxmlformats-officedocument.wordprocessingml.document"

                # .doc 文件头 (D0 CF 11 E0 A1 B1 1A E1)
                if file_content[0:8] == b'\xD0\xCF\x11\xE0\xA1\xB1\x1A\xE1':
                    return "application/msword"

            # 尝试使用python-magic库（如果安装）
            try:
                import magic
                mime = magic.Magic(mime=True)
                return mime.from_buffer(file_content)
            except ImportError:
                pass
            except Exception as e:
                logging.warning(f"MIME类型检测失败: {str(e)}")

            # 无法确定类型
            return "application/octet-stream"

# 全局OSS客户端实例
oss_client = OSSClient()

# 文件大小格式化工具 (utils/file_utils.py)
def format_file_size(size_bytes: int) -> str:
    """格式化文件大小为可读字符串"""
    if size_bytes < 1024:
        return f"{size_bytes}B"
    elif size_bytes < 1024 * 1024:
        return f"{size_bytes / 1024:.1f}KB"
    elif size_bytes < 1024 * 1024 * 1024:
        return f"{size_bytes / (1024 * 1024):.1f}MB"
    else:
        return f"{size_bytes / (1024 * 1024 * 1024):.1f}GB"